package cc.mrbird.febs.system.service.impl;

import cc.mrbird.febs.common.baidu.util.FileUtil;
import cc.mrbird.febs.common.baidu.util.ScanUtils;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.common.service.OssService;
import cc.mrbird.febs.common.utils.UUIDUtil;
import cc.mrbird.febs.system.entity.User;
import cc.mrbird.febs.system.mapper.UserMapper;
import cc.mrbird.febs.system.service.IUserScanService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Date;


/**
 * <p>
 * 扫脸库用户信息表 服务实现类
 * </p>
 *
 * @author Macw
 * @since 2019-12-18
 */
@Service
public class UserScanServiceImpl implements IUserScanService {

    private static Logger logger = LoggerFactory.getLogger(UserScanServiceImpl.class);

    @Resource
    private UserMapper userMapper;

    @Resource
    private OssService ossService;

    //本地测试使用的文件夹
//    @Value("${fileconf.userFilesPath}")
    private String userFilesPath = System.getProperty("user.dir")+"/src/main/resources/file/userFilesPath/";

    //临时目录文件夹
//    @Value("${fileconf.userFilesPathTemp}")
    private String userFilesPathTemp = System.getProperty("user.dir")+"/src/main/resources/file/userFilesPathTemp/";

    @Value("${scanconf.groupId}")
    private String GROUP_ID;

    /**
     * 人脸注册
     *
     * @param file 文件
     * @return String
     * @author Macw
     * @since 2019-12-18
     */
    @Override
    @Transactional
    public String resisterFace(MultipartFile file,User currentUser) {
        //先将文件上传到服务器路径
        String fileName = file.getOriginalFilename();
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        String saveFileName = FileUtil.getFileName(suffix);
        //获取上传文件返回的路径
        String filePath ="";
        try {
            //上传文件到本地服务器
            if (!FileUtil.saveFile(userFilesPath + File.separator, saveFileName, file.getInputStream())) {
                logger.info("文件上传失败");
                return "注册失败，内部错误请联系管理员";
            }
            //实际保存到本地服务器上的图片路径
            filePath = userFilesPath + saveFileName;

            String userId = UUIDUtil.getUUID();
            //调用百度的人脸识别的注册接口
            JSONObject jsonObject = new ScanUtils().doRegister(filePath, userId, GROUP_ID);
            //注册成功的图片保存在百度人脸库中的唯一标识
            String faceToken = jsonObject.getJSONObject("result").getString("face_token");

            //调用服务器上传方法
           String serverFilePath = getServerFilePath(file);

            //添加用户的face注册信息
            if (currentUser != null ) {
                currentUser.setFaceUrl(filePath);
                currentUser.setFaceToken(faceToken);
                currentUser.setModifyTime(new Date());
                currentUser.setFaceId(userId);
                currentUser.setGroupId(GROUP_ID);
                userMapper.updateById(currentUser);
                return serverFilePath;
            }
           // -  //没有注册过，则重新注册

            return serverFilePath;
        } catch (Exception e) {
            logger.error("文件上传失败");
            return "注册失败";
        }
    }

    /**
     * 人脸对比
     * @param file   文件
     * @param userId 用户id
     * @return String
     * @author Macw
     * @since 2019-12-18
     */
    @Override
    public FebsResponse compareFace(MultipartFile file, String userId) {
        String newImagePath = getFilePath(file);
        User dbUser = userMapper.selectById(userId);
        String oldImagePath = dbUser.getFaceUrl();
        if (StringUtils.isBlank(oldImagePath)){
            return new FebsResponse().fail().message("您还没有录入人像，无法进行打卡！");
        }
        JSONObject object = new ScanUtils().compareFace(newImagePath, oldImagePath);
        //获取对比的分数
        Double compareScore = object.getJSONObject("result").getDouble("score");
        //对比过后将删除临时文件夹的图片
        deleteTempFile(userFilesPathTemp);
        if (compareScore > 80) {
            return new FebsResponse().success().message("人像相识度为："+compareScore+" 分，打卡成功！");
        }
        return new FebsResponse().fail().message("人像相识度太低，打卡失败！");
    }

    /**
     * 获取上传后的文件路径
     *
     * @param file
     * @return String
     */
    public String getFilePath(MultipartFile file) {
        //先将文件上传到服务器路径
        String fileName = file.getOriginalFilename();
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        String saveFileName = FileUtil.getFileName(suffix);
        try {
//            //上传文件到本地服务器
            boolean flag = FileUtil.saveFile(userFilesPathTemp + File.separator, saveFileName, file.getInputStream());
            if (!flag) {
                return "注册失败，内部错误请联系管理员";
            }
            //实际保存到服务器上的图片路径
            return userFilesPathTemp + saveFileName;
        } catch (Exception e) {
            logger.error("文件上传失败，请检查：{}", e.toString());
            throw new FebsException("文件上传失败，请检查");
        }
    }


    /**
     * 获取上传后的文件路径
     *
     * @param file
     * @return String
     */
    public String getServerFilePath(MultipartFile file) {
        String basePath = "face";
        String filePath = "";
        try {
            //调用服务器上传方法
            if (file != null && file.getSize() > 0) {
                //调用阿里云OSS的上传方法
                filePath = ossService.aliOSSUpload(file, basePath);
                System.out.println("-------"+filePath);
            }
            //实际保存到服务器上的图片路径
            return filePath;
        } catch (Exception e) {
            logger.error("文件上传失败，请检查：{}", e.toString());
            throw new FebsException("文件上传失败，请检查");
        }
    }


    /**
     * 删除某文件夹下上传的临时文件
     *
     * @param temPath
     */
    public void deleteTempFile(String temPath) {
        File ff = new File(temPath);
        //数组指向文件夹中的文件和文件夹
        File[] fi = ff.listFiles();
        //遍历文件和文件夹
        for (File file : fi) {
            file.delete();
        }
    }


}
